package com.aegean.CommercialHotelBookSystem.room.dao.Impl;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.catalina.tribes.transport.RxTaskPool;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.aegean.CommercialHotelBookSystem.factory.HibernateSessionFactory;
import com.aegean.CommercialHotelBookSystem.factory.MyTools;
import com.aegean.CommercialHotelBookSystem.model.Hotel;
import com.aegean.CommercialHotelBookSystem.model.Room;
import com.aegean.CommercialHotelBookSystem.room.dao.IRoomDao;

public class RoomDaoImpl implements IRoomDao {

	@Override
	public Hotel searchHotel(String name) {
		Session session = null;
		Transaction tx = null;
		Query q = null;
		Hotel one = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			q = session.createQuery("from Hotel where hotel_Name=:name");
			q.setString("name", name);
			q.setCacheable(true);
			one = (Hotel) q.uniqueResult();
			tx.commit();
			return one;
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public Session getSession() {
		return HibernateSessionFactory.getSession();

	}

	@Override
	public void closeSession() {
		HibernateSessionFactory.closeSession();
	}

	@Override
	public boolean addRoom(int Hotel_Id, String Hotel_Name, Room one) {
		Session session = null;
		Transaction tx = null;
		Hotel obj = null;
		DetachedCriteria dcr = DetachedCriteria.forClass(Hotel.class);
		if (Hotel_Id == 0 && Hotel_Name != null) {
			dcr.add(Restrictions.eq("hotel_Name", Hotel_Name));
		} else {
			dcr.add(Restrictions.eq("hotel_Id", Hotel_Id));
		}
		try {
			session = getSession();
			tx = session.beginTransaction();
			Criteria ct = dcr.getExecutableCriteria(session);
			ct.setCacheable(true);
			obj = (Hotel) ct.uniqueResult();
			one.setRoom_Hotel(obj);
			session.save(one);
			tx.commit();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
			return false;
		} finally {
			closeSession();
		}
	}

	@Override
	public List<Room> searchRoomList(Hotel one, int intpage, int intpagesize,
			String bedType, String date) {
		int numBegin = 0;
		if (intpage < 1) {
			numBegin = 0;
		} else {
			numBegin = (intpage - 1) * intpagesize;
		}
		DetachedCriteria dcr = DetachedCriteria.forClass(Room.class);
		dcr.add(Restrictions.eq("room_Hotel", one));
		if (bedType != null && !bedType.equals("")) {
			dcr.add(Restrictions.like("room_Type", "%" + bedType + "%"));
		} else if (date != null && !date.equals("")) {
			dcr.add(Restrictions.eq("room_Date", MyTools.toDate(date)));
		}
		Session session = null;
		Transaction tx = null;
		List<Room> rooms = new ArrayList<Room>();
		try {
			session = getSession();
			tx = session.beginTransaction();
			Criteria cr = dcr.getExecutableCriteria(session);
			cr.addOrder(Property.forName("room_Date").desc());
			cr.addOrder(Property.forName("room_TotalMoney").asc());
			cr.setFirstResult(numBegin);
			cr.setMaxResults(intpagesize);
			cr.setCacheable(true);
			rooms = cr.list();
			for (Room room : rooms) {
				Hibernate.initialize(room.getRoom_Hotel());
				break;
			}
			tx.commit();
			return rooms;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public int searchRoomListCount(Hotel one, String bedType, String date) {
		DetachedCriteria dcr = DetachedCriteria.forClass(Room.class);
		dcr.add(Restrictions.eq("room_Hotel", one));
		if (bedType != null && !bedType.equals("")) {
			dcr.add(Restrictions.like("room_Type", "%" + bedType + "%"));
		} else if (date != null && !date.equals("")) {
			dcr.add(Restrictions.eq("room_Date", MyTools.toDate(date)));
		}
		Session session = null;
		Transaction tx = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			Criteria cr = dcr.getExecutableCriteria(session);
			cr.setProjection(Projections.projectionList());
			cr.setCacheable(true);
			int count = (Integer) cr.setProjection(Projections.rowCount())
					.uniqueResult();
			return count;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			closeSession();
		}
	}

	@Override
	public boolean updateRoom(int Room_Id, String Room_Name,
			float Room_TotalMoney, float Room_Discount, int Room_Count,
			String Room_Type, String Room_Date) {
		Session session = null;
		Transaction tx = null;
		Room one = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			one = (Room) session.load(Room.class, Room_Id);
			one.setRoom_Name(Room_Name);
			one.setRoom_TotalMoney(Room_TotalMoney);
			one.setRoom_Discount(Room_Discount);
			one.setRoom_Count(Room_Count);
			one.setRoom_Type(Room_Type);
			one.setRoom_Date(MyTools.toDate(Room_Date));
			tx.commit();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
			return false;
		} finally {
			closeSession();
		}
	}

	@Override
	public boolean deleteRoom(int Room_Id) {
		Session session = null;
		Transaction tx = null;
		Room one = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			one = (Room) session.load(Room.class, Room_Id);
			session.delete(one);
			tx.commit();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
			return false;
		} finally {
			closeSession();
		}
	}

}
